<template>
  <el-card class="mt-10">
    <el-form
      label-width="120px"
      :model="spuFormData"
      ref="addSpuFormRef"
      :rules="spuFormRules"
    >
      <el-form-item label="SPU名称" prop="spuName">
        <el-input
          placeholder="请输入SPU名称"
          v-model="spuFormData.spuName"
        ></el-input>
      </el-form-item>
      <el-form-item label="品牌" prop="tmId">
        <el-select v-model="spuFormData.tmId">
          <el-option
            v-for="tm in trademarkList"
            :label="tm.tmName"
            :key="tm.id"
            :value="tm.id as number"
          />
        </el-select>
      </el-form-item>
      <el-form-item label="SPU描述" prop="description">
        <el-input
          :rows="2"
          type="textarea"
          placeholder="SPU描述"
          v-model="spuFormData.description"
        />
      </el-form-item>
      <el-form-item label="SPU图片" prop="spuImageList">
        <!--  -->
        <el-upload
          class="spu-form"
          v-model:file-list="spuFormData.spuImageList"
          :action="`${BASE_URL}/admin/product/fileUpload`"
          list-type="picture-card"
          :on-preview="handlePictureCardPreview"
          :before-upload="beforeAvatarUpload"
          :on-success="handleAvatarSuccess"
          :limit="MAX_IMG_SPU"
        >
          <el-icon><Plus /></el-icon>
          <template #tip>
            <div class="el-upload__tip">
              只能上传jpg/jpeg/png文件，且不超过200kb
            </div>
          </template>
        </el-upload>

        <el-dialog v-model="dialogVisible" width="30%">
          <img class="spu_img" :src="dialogImageUrl" alt="Preview Image" />
        </el-dialog>
      </el-form-item>
      <el-form-item label="销售属性">
        <el-select
          :placeholder="
            newSaleAttrList.length
              ? `还剩${newSaleAttrList.length}个未选择`
              : '这下好了,大家都没得选了'
          "
          v-model="saleAttrValue"
        >
          <el-option
            v-for="baseSaleAttr in newSaleAttrList"
            :label="baseSaleAttr.name"
            :key="baseSaleAttr.id"
            :value="`${baseSaleAttr.id}:${baseSaleAttr.name}`"
          ></el-option>
        </el-select>
        <el-button
          type="primary"
          :icon="Plus"
          class="marginBtn"
          @click="addSaleAttr"
          :disabled="!saleAttrValue"
        >
          添加销售属性
        </el-button>
      </el-form-item>
      <el-form-item prop="spuSaleAttrList">
        <el-table :data="spuFormData.spuSaleAttrList" border>
          <el-table-column label="序号" type="index" width="60" />
          <el-table-column label="属性名" width="120" prop="saleAttrName" />
          <el-table-column label="属性值名称列表">
            <template v-slot="{ row }">
              <el-tag
                v-for="(baseValue, index) in row.spuSaleAttrValueList"
                :key="baseValue.saleAttrValueName"
                class="mr-10"
                closable
                @close="removeSaleAttrValueName(row, index)"
              >
                {{ baseValue.saleAttrValueName }}
              </el-tag>
              <el-input
                size="small"
                v-if="row.isEdit"
                style="width: 120px"
                ref="inputRef"
                v-model="saleAttrValueName"
                @blur="inputBlur(row)"
              />
              <el-button
                :icon="Plus"
                size="small"
                v-else
                @click="setIsShow(row)"
              />
            </template>
          </el-table-column>
          <el-table-column label="操作" width="120">
            <template v-slot="{ $index }">
              <el-button
                type="danger"
                :icon="Delete"
                size="small"
                @click="deleteSaleAttr($index)"
              ></el-button>
            </template>
          </el-table-column>
        </el-table>
      </el-form-item>
      <el-form-item>
        <el-button type="primary" @click="addOrUpdateSpu">保存</el-button>
        <el-button @click="emit('isShow', 1)">取消</el-button>
      </el-form-item>
    </el-form>
  </el-card>
</template>

<script lang="ts">
export default {
  name: "AddOrUpdateSpu",
};
</script>

<script lang="ts" setup>
import { ref, nextTick, onMounted, reactive, computed } from "vue";
import { ElMessage } from "element-plus";
import { Plus, Delete } from "@element-plus/icons-vue";
import { getAllTrademarkListApi } from "@/api/product/trademark";
import {
  getBaseSaleAttrListApi,
  postSpuSaleAttrApi,
  getSpuImgListApi,
  getSpuSaleAttrListApi,
  postSpuSaleAttrListApi,
} from "@/api/product/spu";
import type { ItrademarkModelList } from "@/api/product/model/trademarkModel";
import type {
  BaseSaleAttrList,
  SpuCompontent,
  SpuSaleAttrItem,
} from "@/api/product/model/spuModel";
import type { FormInstance, FormRules } from "element-plus";

import type { UploadProps } from "element-plus";
import { useCartgroyStroe } from "@/stores/cartgroy";
import { useSpuStore } from "@/stores/spu";

// 最大上传数量
const BASE_URL = import.meta.env.VITE_API_URL;

// form实例
const addSpuFormRef = ref<FormInstance>();

// 自定义校验规则
const spuSaleAttrListRules = (rulea: any, value: any, callback: any) => {
  if (!value.length) {
    callback(new Error("请至少添加一个属性"));
    return;
  }
  if (
    !value.every(
      (attrValue: SpuSaleAttrItem) => attrValue.spuSaleAttrValueList.length
    )
  ) {
    callback(new Error("属性值不能为空"));
    return;
  }
  callback();
};

// 校验规则
const spuFormRules = reactive<FormRules>({
  // tmName: [{ required: true, message: "请输入品牌名称", trigger: "blur" }],
  spuName: [{ required: true, message: "请输入SPU名称", trigger: "blur" }],
  tmId: [{ required: true, message: "请选择品牌", trigger: "change" }],
  description: [{ required: true, message: "请输入SPU描述", trigger: "blur" }],
  spuImageList: [{ required: true, message: "请上传SPU图片" }],
  spuSaleAttrList: [
    {
      required: true,
      validator: spuSaleAttrListRules,
      trigger: "blur",
    },
  ],
});

const saleAttrValue = ref("");

// 创建新数组 用来实现交互
const newSaleAttrList = computed(() => {
  /*
  filter： 返回值为true  数据保留 值为false 数据过滤
    过滤返回值为true的数据
  */
  return baseSaleAttrList.value.filter((baseSaleAttr) => {
    return !spuFormData.spuSaleAttrList.some((spuSaleAttr) => {
      return spuSaleAttr.baseSaleAttrId === baseSaleAttr.id;
    });
  });
});
// 点击添加销售属性
const addSaleAttr = () => {
  const [id, name] = saleAttrValue.value.split(":");
  spuFormData.spuSaleAttrList.push({
    baseSaleAttrId: +id,
    saleAttrName: name,
    spuSaleAttrValueList: [],
    isEdit: true,
  });
  // 设置option的值为空
  saleAttrValue.value = "";
  // 清除表格的校验
  addSpuFormRef.value?.clearValidate(["spuSaleAttrList"]);
};

// 点击删除销售属性
const deleteSaleAttr = (index: number) => {
  spuFormData.spuSaleAttrList.splice(index, 1);
};

const spuStore = useSpuStore();
// 原始数据
const spuFormData = reactive<SpuCompontent>({
  spuName: spuStore.spuName,
  tmId: spuStore.tmId,
  description: spuStore.description,
  spuImageList: [],
  spuSaleAttrList: [],
});

const dialogImageUrl = ref("");
const dialogVisible = ref(false);
const MAX_IMG_SPU = 2;

const handlePictureCardPreview: UploadProps["onPreview"] = (uploadFile) => {
  dialogImageUrl.value = uploadFile.url as string;
  dialogVisible.value = true;
};

const cartgroyStroe = useCartgroyStroe();
// 点击保存提交
const addOrUpdateSpu = async () => {
  await addSpuFormRef.value?.validate();
  const id = spuStore.id;
  const data = {
    ...spuFormData,
    spuImageList: spuFormData.spuImageList.map((img) => {
      return {
        imgName: img.name,
        imgUrl: img.response
          ? (img.response as { data: string }).data
          : (img.url as string),
      };
    }),
    category3Id: cartgroyStroe.cartgroy3Id as number,
    tmId: spuFormData.tmId as number,
  };
  if (id) {
    await postSpuSaleAttrListApi({
      ...data,
      id,
    });
  } else {
    await postSpuSaleAttrApi(data);
  }

  ElMessage.success(`${id ? "修改" : "添加"}SPU成功`);
  emit("isShow", 1);
};

const isShowUpload = computed(() => {
  return spuFormData.spuImageList.length >= MAX_IMG_SPU
    ? "none"
    : "inline-flex";
});

// 上传图片之前的校验
const beforeAvatarUpload: UploadProps["beforeUpload"] = (rawFile) => {
  // rawFile.type  上传图片类型
  // rawFile.size  上传图片大小
  const rawFileType = ["image/jpeg", "image/jpg", "image/png"];
  if (!rawFileType.includes(rawFile.type)) {
    ElMessage.error("上传的图片必须为jpeg、jpg或者png");
    return false; //返回false取消上传
  } else if (rawFile.size / 1024 > 250) {
    ElMessage.error("图片大小不能超过250Kb");
    return false;
  }
  return true; //返回true确认上传
};

// 图片上传成功
const handleAvatarSuccess = () => {
  // 有图片时只校验一次
  if (spuFormData.spuImageList.length !== 1) return;
  // addSpuFormRef.value?.clearValidate();
  // console.log(111);
};

// 表格输入框实例
const inputRef = ref();
const trademarkList = ref<ItrademarkModelList>([]);
const baseSaleAttrList = ref<BaseSaleAttrList>([]);

// 挂载阶段接收下拉单数据
onMounted(async () => {
  trademarkList.value = await getAllTrademarkListApi();
});
onMounted(async () => {
  baseSaleAttrList.value = await getBaseSaleAttrListApi();
});
// 修改时获取图片列表
onMounted(async () => {
  const id = spuStore.id;
  if (id) {
    const spuImageList = await getSpuImgListApi(id as number);
    spuFormData.spuImageList = spuImageList.map((img) => {
      return {
        name: img.imgName,
        url: img.imgUrl,
      };
    });
  }
});
// 修改时获取属性值列表
onMounted(async () => {
  const id = spuStore.id;
  if (id) {
    spuFormData.spuSaleAttrList = await getSpuSaleAttrListApi(id as number);
  }
});

// 切换编辑显示
const setIsShow = async (row: SpuSaleAttrItem) => {
  row.isEdit = true;
  await nextTick();
  inputRef.value.focus();
};

// 定义一个新的数据用来保存表格里面input的值
const saleAttrValueName = ref("");

// 表格输入框失去焦点
const inputBlur = (row: SpuSaleAttrItem) => {
  if (saleAttrValueName.value) {
    row.spuSaleAttrValueList.push({
      baseSaleAttrId: row.baseSaleAttrId,
      saleAttrValueName: saleAttrValueName.value,
    });
    // 清空input数据
    saleAttrValueName.value = "";
  }
  row.isEdit = false;
};

// 点击删除tag
const removeSaleAttrValueName = (row: SpuSaleAttrItem, index: number) => {
  row.spuSaleAttrValueList.splice(index, 1);
};

const emit = defineEmits(["isShow"]);
</script>

<style scoped>
.avatar-uploader .avatar {
  width: 178px;
  height: 178px;
  display: block;
}

.spu-form :deep(.el-upload) {
  display: v-bind(isShowUpload);
}
.spu_img {
  width: 100%;
}
.marginBtn {
  margin-left: 20px;
}
</style>
